package com.climb.moive.framework.mvc;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;

/**
 * @author Administrator
 */
public abstract class BaseController extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String result = null;
        /*
            1. 获取method值
            如果method为null，则使用默认值
         */
        String method = req.getParameter("method");
        if((method == null ) || (method.equals(""))) {
            result = index(req,resp);

        }else{
        /*
            2. 根据method，使用反射调用相应处理方法
         */
            try {
                Method httpMethod = this.getClass().getMethod(method, HttpServletRequest.class, HttpServletResponse.class);
                // 通过反射来调用方法
                result = (String)httpMethod.invoke(this, req, resp);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }



        /*
            3. 根据方法的返回结果，决定返回方式
             *    forward：请求转发（request.attribute、相对url）
             *    redirect：重定向(绝对url)
             *    response：用户自定义（如文件下载、JSON）
             *
             *    在各个业务方法中，返回值的类型为String。
             *    如果业务方法的结果使用forward方式返回，有两种写法：
             *        /index.jsp
             *        forward:/index.jsp
             *    如果业务方法的结果使用redirect方式返回，有一种写法：
             *        redirect:/MovieProject/MemberIndex
             *    如果业务方法自己使用response返回结果，那么返回值是null.
             *        null
         */
        //如果业务方法自己使用response返回结果，那么返回值是null.
        if (result == null || result.trim().isEmpty()) {
            return;
        }

        if (!result.contains(":")) {
            // 如果业务方法的结果使用forward方式返回，格式 /index.jsp"
            req.getRequestDispatcher(result).forward(req, resp);
        } else {
            /*
             *  这里有两种情形处理：
             *  	forward:/index.jsp
             *  	redirect:/MovieProject/MemberIndex
             */
            int index = result.indexOf(":");
            String bz = result.substring(0, index);        //forward或redirect
            String path = result.substring(index + 1);    //url

            // 如果是forward
            if (bz.equalsIgnoreCase("forward")) {
                req.getRequestDispatcher(path).forward(req, resp);
            } else if (bz.equalsIgnoreCase("redirect")) {
                // 如果是redirect
                resp.sendRedirect(path);
            } else {
                // 这里不应该运行。如果运行，就是程序有错
                throw new RuntimeException("业务方法返回的结果类型出错，请使用forward或redirect");
            }
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }

    // 默认首页
    protected abstract String index(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException  ;
}
